/*
 * Carga.cpp
 *
 *  Created on: Apr 22, 2014
 *      Author: carlos
 */

#include "Carga.h"
#include "../../logical_layer/entities/Twit.h"
#include "../../logical_layer/hash/HashExtensible.h"
#include "../../logical_layer/parser/TwitParser.h"
#include "../../logical_layer/entities/Rss.h"
#include "../../logical_layer/hash/HashExtensibleRss.h"
#include "../../logical_layer/parser/RssParser.h"

#include "../../logical_layer/hash/Const.h"
#include "../../../src/utils/types.h"


Carga::Carga(string claveComando, string tipoCarga, string tipoComandoLeyenda,FileHandler* fileHandler) :
		Command(claveComando, tipoComandoLeyenda,fileHandler), tipoCarga(tipoCarga) {
}

void Carga::execute(int argc, char** argv) {

	//tomar el directorio de archivos de donde obtener los nuevos Twits o RSSs
	if ( argc > 2 )
	{
		string directorio_nuevos(argv[2]);
	}

	if (CARGA_TWEET == this->tipoCarga)
	{

		vector<Twit*> twits;

		//Con un puntero a DIR abriremos el directorio
		DIR *dir;

		// en *ent habrá información sobre el archivo que se está "sacando" a cada momento
		struct dirent *ent;

		// Empezaremos a leer en el directorio actual
		string directorio("datos/twits/");
		dir = opendir (directorio.c_str());

		// Miramos que no haya error
		if (dir == NULL)
		{
			// perror() devuelve la cadena S y el error (en cadena de caracteres) que tenga errno
			perror ("No puedo abrir el directorio");
			exit(EXIT_FAILURE);
		}

		// Leyendo uno a uno todos los archivos que hay
		while ((ent = readdir (dir)) != NULL)
		{
			string nombre_archivo_twit = Utils::getNombreArchivo(ent,"twt");
			if ( nombre_archivo_twit != "" )
			{
				//cout<<endl<<"####################################################"<<endl;
				//cout<<"##procesando "<<nombre_archivo_twit<<" ... "<<endl;

				nombre_archivo_twit = directorio+nombre_archivo_twit;

				FILE * fp;
				char linea[Const::TAM_MAX_LINEA_TWIT];


				fp = fopen (nombre_archivo_twit.c_str() , "r");

				if (fp == NULL )
				{
				   string error_openFile = "Error al abrir archivo "+nombre_archivo_twit;
				   perror (error_openFile.c_str());

				}
				else
				{
				   TwitParser twitParser;

				   srand(time(NULL));

				   Twit* twit = new Twit();

				   while (fgets(linea, Const::TAM_MAX_LINEA_TWIT, fp) != NULL)
				   {
					   twit = twitParser.parsearLinea(linea);
					   //cout<<"// AGREGANDO: Twit "<<twit->getId()<<endl;
					   bool hashingAddOK = this->fileHandler->getHash()->doHashingAdd(twit);
					   if ( hashingAddOK )
					   {
						   twits.push_back(twit);
					   }else{
						   cout<<"No se indexara el twit "<<twit->getId()<<endl;
					   }

				   }

				}

				fclose(fp);

			}

		}

		closedir(dir);

		/*
		cout<<"cant_bloques: "<<this->fileHandler->getHash()->getFileHash()->elementos()<<endl;
		cout<<"muestro los twits cargados en el archivo"<<endl;
		for ( unsigned i=0 ; i < this->fileHandler->getHash()->getFileHash()->elementos() ; i++)
		{
			cout<<*(this->fileHandler->getHash()->leerDeArchivo(i))<<endl;
		}
		*/

		vector<Twit*>::iterator it;

		IndexadorTwit* indexadorTwit=this->fileHandler->getIndexadorTwit();

		for (it = twits.begin(); it != twits.end(); it++) {
			indexadorTwit->add((*it));
		}
		cout<<"Se cargaron "<<twits.size()<<" twits en "<<BLOQUES_HASH_FILE<<endl;
	}


	if( CARGA_RSS==this->tipoCarga ){

		vector<Rss*> rsses;

		//Con un puntero a DIR abriremos el directorio
		DIR *dir2;

		// en *ent habrá información sobre el archivo que se está "sacando" a cada momento
		struct dirent *ent2;

		// Empezaremos a leer en el directorio actual
		string directorio2("datos/rss/");
		dir2 = opendir (directorio2.c_str());

		// Miramos que no haya error */
		if (dir2 == NULL)
		{
			// perror() devuelve la cadena S y el error (en cadena de caracteres) que tenga errno
			perror ("No puedo abrir el directorio");
			exit(EXIT_FAILURE);
		}

		// Leyendo uno a uno todos los archivos que hay
		while ((ent2 = readdir (dir2)) != NULL)
		{
			string nombre_archivo_rss = Utils::getNombreArchivo(ent2,"rss");
			if ( nombre_archivo_rss != "" )
			{
				//cout<<endl<<"####################################################"<<endl;
				//cout<<"##procesando "<<nombre_archivo_rss<<" ... "<<endl;

				nombre_archivo_rss = directorio2+nombre_archivo_rss;

				FILE * fp2;
				char linea2[Const::TAM_MAX_LINEA_RSS];


				fp2 = fopen (nombre_archivo_rss.c_str() , "r");

				if (fp2 == NULL )
				{
				   string error_openFile2 = "Error al abrir archivo "+nombre_archivo_rss;
				   perror (error_openFile2.c_str());

				}
				else
				{
				   RssParser rssParser;

				   srand(time(NULL));

				   while (fgets(linea2, Const::TAM_MAX_LINEA_RSS, fp2) != NULL)
				   {
					   Rss* rss = new Rss();

					   int nextId = IDGenerator::getInstance()->getNextID(ConfigurationMannagerPool::getInstance(RSS)->getSequenceName());
					   rss->setId(nextId);

					   string title = rssParser.parsearlinea(linea2, NAME_TITLE);
					   rss->setTitulo(title);

					   if ( fgets(linea2, Const::TAM_MAX_LINEA_RSS, fp2) != NULL )
					   {
						   string descripcion = rssParser.parsearlinea(linea2, NAME_DESCRIPTION);
						   rss->setDescripcion(descripcion);
					   }

					   //cout<<"// AGREGANDO: RSS "<<rss->getId()<<endl;
					   bool hashingAddOK = this->fileHandler->getHashRss()->doHashingAdd(rss);
					   if ( hashingAddOK )
					   {
						   rsses.push_back(rss);
					   }else{
						   cout<<"No se indexara el rss "<<rss->getId()<<endl;
					   }

				   }

				}

				fclose(fp2);
			}

		}

		closedir(dir2);


		/*
		cout<<"cant_bloques: "<<this->fileHandler->getHashRss()->getFileHash()->elementos()<<endl;
		cout<<"muestro los rsses cargados en el archivo"<<endl;
		for ( unsigned i=0 ; i < this->fileHandler->getHashRss()->getFileHash()->elementos() ; i++)
		{
			cout<<*(this->fileHandler->getHashRss()->leerDeArchivo(i))<<endl;
		}
		*/

		vector<Rss*>::iterator it;

		IndexadorRss* indexadorRss = this->fileHandler->getIndexadorRss();
		for (it = rsses.begin(); it != rsses.end(); it++) {
			indexadorRss->add((*it));
		}
		cout<<"Se cargaron "<<rsses.size()<<" rsses en "<<BLOQUES_HASH_RSS_FILE<<endl;

	 }
}

Carga::~Carga() {

}

